package com.tianji.learning.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.cache.CategoryCache;
import com.tianji.api.client.course.CatalogueClient;
import com.tianji.api.client.course.CourseClient;
import com.tianji.api.client.search.SearchClient;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.course.CataSimpleInfoDTO;
import com.tianji.api.dto.course.CourseFullInfoDTO;
import com.tianji.api.dto.course.CourseSimpleInfoDTO;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.ObjectUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.dto.QuestionFormDTO;
import com.tianji.learning.domain.page.QuestionAdminPageQuery;
import com.tianji.learning.domain.page.QuestionPageQuery;
import com.tianji.learning.domain.po.InteractionQuestion;
import com.tianji.learning.domain.po.InteractionReply;
import com.tianji.learning.domain.vo.QuestionAdminVO;
import com.tianji.learning.domain.vo.QuestionVO;
import com.tianji.learning.mapper.InteractionQuestionMapper;
import com.tianji.learning.mapper.InteractionReplyMapper;
import com.tianji.learning.service.IInteractionQuestionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 互动提问的问题表 服务实现类
 * </p>
 *
 * @author ffk
 * @since 2024-06-25
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class InteractionQuestionServiceImpl extends ServiceImpl<InteractionQuestionMapper, InteractionQuestion> implements IInteractionQuestionService {

    private final UserClient userClient;
    private final InteractionReplyMapper interactionReplyMapper;
    private final SearchClient searchClient;
    private final InteractionReplyMapper replyMapper;

    private final CourseClient courseClient;
    private final CatalogueClient catalogueClient;
    private final CategoryCache categoryCache;

    /**
     * 1 新增提问
     * @param questionFormDTO 请求参数
     */
    @Override
    public void addQuestion(QuestionFormDTO questionFormDTO) {
         InteractionQuestion interactionQuestion = BeanUtils.toBean(questionFormDTO, InteractionQuestion.class);

         interactionQuestion.setUserId(UserContext.getUser());

         save(interactionQuestion);
    }

    /**
     * 2 用户端-修改问题
     * @param id 问题id
     * @param questionFormDTO 修改参数
     */
    @Override
    public void updateQuestionById(Long id, QuestionFormDTO questionFormDTO) {
        InteractionQuestion byId = getById(id);
        if(!byId.getUserId().equals(UserContext.getUser())){
            throw new BadRequestException("不能修改自己的问题");
        }

        boolean result = this.lambdaUpdate()
                .set(ObjectUtils.isNotEmpty(questionFormDTO.getTitle()),InteractionQuestion::getTitle, questionFormDTO.getTitle())
                .set(ObjectUtils.isNotEmpty(questionFormDTO.getDescription()),InteractionQuestion::getDescription, questionFormDTO.getDescription())
                .set(ObjectUtils.isNotEmpty(questionFormDTO.getAnonymity()),InteractionQuestion::getAnonymity, questionFormDTO.getAnonymity())
                .eq(InteractionQuestion::getId, id)
                //.eq(InteractionQuestion::getUserId,UserContext.getUser())
                .update();

        if(!result){
            throw new BadRequestException("更新问题失败");
        }
    }


    /**
     * 3 用户 分页查询问题
     * @param pageQuery 分页查询问题参数
     * @return 分页查询返回
     */
    @Override
    public PageDTO<QuestionVO> userQueryPage(QuestionPageQuery pageQuery) {
        if(ObjectUtils.isEmpty(pageQuery.getCourseId()) && ObjectUtils.isEmpty(pageQuery.getSectionId())){
            throw new BadRequestException("sectionid和courseId不能同时为空");
        }

        //分页查询
        Page<InteractionQuestion> pageResult = this.lambdaQuery()
                .select(InteractionQuestion.class, info -> !info.getProperty().equals("description"))
                .eq(ObjectUtils.isNotEmpty(pageQuery.getCourseId()), InteractionQuestion::getCourseId, pageQuery.getCourseId())
                .eq(ObjectUtils.isNotEmpty(pageQuery.getSectionId()), InteractionQuestion::getSectionId, pageQuery.getSectionId())
                .eq(pageQuery.getOnlyMine(), InteractionQuestion::getUserId, UserContext.getUser())
                .eq(InteractionQuestion::getHidden,false)
                .page(pageQuery.toMpPageDefaultSortByCreateTimeDesc());

         List<InteractionQuestion> records = pageResult.getRecords();
         //判空啊啊啊
         if(ObjectUtils.isEmpty(records)){
             return PageDTO.empty(pageResult);
         }

         //获取所有提问者id和最后一次回答者id
        Set<Long> userAndLatestReplyUserIds=new HashSet<>();
        Set<Long> questionIds=new HashSet<>();
        for (InteractionQuestion record : records) {
            if(!record.getAnonymity()){
                userAndLatestReplyUserIds.add(record.getUserId());
                userAndLatestReplyUserIds.add(record.getLatestAnswerId());
                questionIds.add(record.getId());
            }
        }



        //一起查出来哈哈
         List<UserDTO> userInfo = userClient.queryUserByIds(userAndLatestReplyUserIds);

        Map<Long, UserDTO> userMap = new HashMap<>(userAndLatestReplyUserIds.size()+1);
        if(ObjectUtils.isNotEmpty(userInfo)){
            userMap=userInfo.stream().collect(Collectors.toMap(UserDTO::getId, userDTO -> userDTO));
        }

        //把最近一次回答的内容查出来
        questionIds.remove(null);
        Map<Long,InteractionReply > contentMap = new HashMap<>(questionIds.size());

        if(CollUtils.isNotEmpty(questionIds)){
            List<InteractionReply> replies  = interactionReplyMapper.selectBatchIds(questionIds);
            for (InteractionReply reply : replies) {
                contentMap.put(reply.getId(),reply);
                if(!reply.getAnonymity()){
                    userAndLatestReplyUserIds.add(reply.getUserId());
                }
            }

        }
//        if(ObjectUtils.isNotEmpty(latestContents)){
//            contentMap=latestContents.stream().collect(Collectors.toMap(InteractionReply::getUserId, InteractionReply::getContent));
//        }


        List<QuestionVO> voList=new ArrayList<>();
        for (InteractionQuestion record : records) {
            QuestionVO questionVO = BeanUtils.copyBean(record, QuestionVO.class);
            questionVO.setUserId(null);
            voList.add(questionVO);

            if(!record.getAnonymity()){
                UserDTO userDTO = userMap.get(record.getUserId());
                if(userDTO!=null){
                    questionVO.setUserId(userDTO.getId());
                    questionVO.setUserName(userDTO.getName());
                    questionVO.setUserIcon(userDTO.getIcon());
                }


            }

            InteractionReply reply = contentMap.get(record.getLatestAnswerId());
            if (reply != null) {
                questionVO.setLatestReplyContent(reply.getContent());
                if(!reply.getAnonymity()){// 匿名用户直接忽略
                    UserDTO user = userMap.get(reply.getUserId());
                    questionVO.setLatestReplyUser(user.getName());
                }

            }

           // voList.add(questionVO);
        }

        return PageDTO.of(pageResult, voList);
    }


    /**
     * 4 用户 根据问题id获取问题详情
     * @param id 问题id
     * @return 一个问题详情
     */
    @Override
    public QuestionVO getQuestionDetailByQuestionId(Long id) {

         InteractionQuestion questionInfo = getById(id);
         //隐藏或者为空要返回null
        if(ObjectUtils.isEmpty(questionInfo) || questionInfo.getHidden()){
            return null;
        }

         QuestionVO questionVO = BeanUtils.copyBean(questionInfo, QuestionVO.class);

        UserDTO userInfo=null;
        //匿名就不用查了。。。
        if(!questionInfo.getAnonymity()){
            userInfo = userClient.queryUserById(questionInfo.getUserId());
        }

        //所以这里也要判空。。。
        if(ObjectUtils.isNotEmpty(userInfo) || userInfo!=null){
            questionVO.setUserName(userInfo.getName());
            questionVO.setUserIcon(userInfo.getIcon());
        }
        return questionVO;
    }

    /**
     * 5 用户端-删除问题
     * @param id 问题id
     */
    @Override
    public void deleteQuestionById(Long id) {
        //判断是否是当前用户的问题
        InteractionQuestion msg = this.getById(id);
        if(!msg.getUserId().equals(UserContext.getUser())){
            throw new BadRequestException("不是自己的问题不能删");
        }

        boolean result = removeById(id);
        if(!result){
            throw new BadRequestException("用户端删除问题失败");
        }

        //删除回答
        replyMapper.delete(new LambdaQueryWrapper<InteractionReply>().eq(InteractionReply::getQuestionId,id));
    }


    /**
     * 6 管理端 分页查询问题
     * @param pageQuery 管理端分页查询参数
     * @return 返回分页信息
     */
    @Override
    public PageDTO<QuestionAdminVO> adminQueryPage(QuestionAdminPageQuery pageQuery) {

        //es查询 根据coursename,课程的模糊名称查询到课程的ids
        List<Long> courseIds=null;
        if(ObjectUtils.isNotEmpty(pageQuery.getCourseName())){
            courseIds=searchClient.queryCoursesIdByName(pageQuery.getCourseName());
            if(ObjectUtils.isEmpty(courseIds)){
                return PageDTO.empty(0L, 0L);
            }
        }

        Page<InteractionQuestion> pageResult = this.lambdaQuery()
                .ge(ObjectUtils.isNotEmpty(pageQuery.getBeginTime()), InteractionQuestion::getCreateTime, pageQuery.getBeginTime())
                .le(ObjectUtils.isNotEmpty(pageQuery.getEndTime()), InteractionQuestion::getCreateTime, pageQuery.getEndTime())
                .eq(ObjectUtils.isNotEmpty(pageQuery.getStatus()), InteractionQuestion::getStatus, pageQuery.getStatus())
                .in(courseIds!=null,InteractionQuestion::getCourseId, courseIds)
                .page(pageQuery.toMpPageDefaultSortByCreateTimeDesc());

        //数据list集合
         List<InteractionQuestion> records = pageResult.getRecords();
        if(ObjectUtils.isEmpty(records)){
            return PageDTO.empty(pageResult);
        }

        //用户ids
        Set<Long> idsList=new HashSet<>();
        //课程ids
        Set<Long> courseIdsList=new HashSet<>();
        //章节ids
        Set<Long> chapterAndSectionIdsList=new HashSet<>();

        //填充
        for (InteractionQuestion record : records) {
            idsList.add(record.getUserId());
            courseIdsList.add(record.getCourseId());
            chapterAndSectionIdsList.add(record.getChapterId());
            chapterAndSectionIdsList.add(record.getSectionId());
        }


        //收集用户信息
        List<UserDTO> userinfos = userClient.queryUserByIds(idsList);
        Map<Long, UserDTO> userMap = new HashMap<>();
        if(ObjectUtils.isNotEmpty(userinfos)){
            userMap=userinfos.stream().collect(Collectors.toMap(UserDTO::getId, UserDTO -> UserDTO));
        }

        //收集课程信息，拼接三级分类
        List<CourseSimpleInfoDTO> courseInfoList = courseClient.getSimpleInfoList(courseIdsList);
        Map<Long, CourseSimpleInfoDTO> courseInfoMap = new HashMap<>();
        if(ObjectUtils.isNotEmpty(courseInfoList)){
           courseInfoMap = courseInfoList.stream().collect(Collectors.toMap(CourseSimpleInfoDTO::getId, CourseSimpleInfoDTO -> CourseSimpleInfoDTO));

        }

        //收集章节和小节信息，即目录信息
        List<CataSimpleInfoDTO> cataSimpleInfoDTOS = catalogueClient.batchQueryCatalogue(chapterAndSectionIdsList);
        Map<Long, String> chapterAndSectionInfoMap=new HashMap<>();
        if(ObjectUtils.isNotEmpty(cataSimpleInfoDTOS)){
            chapterAndSectionInfoMap = cataSimpleInfoDTOS.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId, CataSimpleInfoDTO::getName));
        }

        List<QuestionAdminVO> voList=new ArrayList<>();
        for (InteractionQuestion record : records) {
            QuestionAdminVO questionAdminVO = BeanUtils.copyBean(record, QuestionAdminVO.class);

            questionAdminVO.setUserName(userMap.get(record.getUserId()).getName());
            questionAdminVO.setUserIcon(userMap.get(record.getUserId()).getIcon());

             questionAdminVO.setAnswerAmounts(record.getAnswerTimes());

             questionAdminVO.setCourseName(courseInfoMap.get(record.getCourseId()).getName());
             questionAdminVO.setCategoryName(categoryCache.getCategoryNames(courseInfoMap.get(record.getCourseId()).getCategoryIds()));

            questionAdminVO.setChapterName(chapterAndSectionInfoMap.getOrDefault(record.getChapterId(), ""));
            questionAdminVO.setSectionName(chapterAndSectionInfoMap.getOrDefault(record.getSectionId(), ""));

             voList.add(questionAdminVO);
        }
        return PageDTO.of(pageResult,voList);
    }

    /**
     * 7、管理端-隐藏或者显示问题
     * @param id 问题ID
     * @param hidden 隐藏参数，隐藏则为true
     */
    @Override
    public void updateAdminQuestionHidden(Long id, Boolean hidden) {
        boolean result = this.lambdaUpdate()
                .set(hidden != null, InteractionQuestion::getHidden, hidden)
                .eq(InteractionQuestion::getId, id)
                .update();

        if(!result){
            throw new BadRequestException("管理端更新问题失败");
        }
    }


    /**
     * 8、管理端 - 根据ID查询互动问题
     *
     * @param id 问题ID
     */
    @Override
    public QuestionAdminVO adminQueryById(Long id) {
        if (id == null) {
            throw new RuntimeException("问题id不能为空");
        }
        //查出来
        InteractionQuestion question = lambdaQuery().eq(InteractionQuestion::getId, id).one();
        if (ObjectUtil.isEmpty(question)) {
            throw new RuntimeException("问题不存在");
        }

        //返回vo
        QuestionAdminVO questionAdminVO = BeanUtils.copyBean(question, QuestionAdminVO.class);

        //用户id，准备远程调用
        Set<Long> userAndTeachIds = new HashSet<>();
        //用户id加入集合
        userAndTeachIds.add(question.getUserId());

        //根据课程id去得到老师id
        Long courseId = question.getCourseId();
        CourseFullInfoDTO courseInfo = courseClient.getCourseInfoById(courseId, false, true);
        List<Long> teacherIds= new ArrayList<>();
        if(ObjectUtils.isNotEmpty(courseInfo)){
            //老师id集合
            teacherIds= courseInfo.getTeacherIds();
        }
        //转set
         Set<Long> teacherIdsSet = teacherIds.stream().collect(Collectors.toSet());

        for (Long teacherId : teacherIdsSet) {
            if(teacherId!=null){
                //老师id加入集合
                userAndTeachIds.add(teacherId);
            }
        }

        //查用户和老师信息
         List<UserDTO> userAndTeachInfo = userClient.queryUserByIds(userAndTeachIds);
         Map<Long, UserDTO>  userAndTeachInfoMap=new HashMap<>();
        if(ObjectUtils.isNotEmpty(userAndTeachInfo)){
            userAndTeachInfoMap = userAndTeachInfo.stream().collect(Collectors.toMap(UserDTO::getId, UserDTO -> UserDTO));
        }

        //回答数量
        questionAdminVO.setAnswerAmounts(question.getAnswerTimes());
        //用户信息
        questionAdminVO.setUserName(userAndTeachInfoMap.get(question.getUserId()).getName());
        questionAdminVO.setUserIcon(userAndTeachInfoMap.get(question.getUserId()).getIcon());
        //老师信息
        StringBuffer teacherName=new StringBuffer();
        int flag=0;
        for (Long teacherId : teacherIdsSet) {
            flag++;
            if(teacherId!=null){
                if(flag == teacherIdsSet.size()){
                    teacherName.append(userAndTeachInfoMap.get(teacherId).getName());
                }else{
                    teacherName.append(userAndTeachInfoMap.get(teacherId).getName()+",");
                }
            }
        }
        //设置老师名称
        questionAdminVO.setTeacherName(teacherName.toString());
        //查询课程名称并设置
        List<CourseSimpleInfoDTO> courseInfoList = courseClient.getSimpleInfoList(List.of(courseId));
        Map<Long, String> courseInfoMap = new HashMap<>();
        if(ObjectUtils.isNotEmpty(courseInfoList)){
            courseInfoMap=courseInfoList.stream().collect(Collectors.toMap(CourseSimpleInfoDTO::getId, CourseSimpleInfoDTO::getName));
        }
        questionAdminVO.setCourseName(courseInfoMap.getOrDefault(courseId, ""));

        //设置章节小节信息，分类名称
        Set<Long> chapterAndSectionIdsList=new HashSet<>();
        chapterAndSectionIdsList.add(question.getChapterId());
        chapterAndSectionIdsList.add(question.getSectionId());
        List<CataSimpleInfoDTO> cataInfoList = catalogueClient.batchQueryCatalogue(chapterAndSectionIdsList);
        Map<Long, String> cataInfoMap = new HashMap<>(chapterAndSectionIdsList.size());
        if (ObjectUtil.isNotEmpty(cataInfoList)) {
            cataInfoMap = cataInfoList.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId, CataSimpleInfoDTO::getName));
        }
        //章节小节名称
        questionAdminVO.setChapterName(cataInfoMap.getOrDefault(question.getChapterId(), ""));
        questionAdminVO.setSectionName(cataInfoMap.getOrDefault(question.getSectionId(), ""));
        //分类名称
        questionAdminVO.setCategoryName(categoryCache.getCategoryNames(courseInfo.getCategoryIds()));

        return questionAdminVO;
    }

}
